package utils;
import flixel.FlxBasic;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.util.FlxPoint;


//////////////////////////////////////////////////////////////////
/// \class: Frame
/// \brief: Es un cuadro que enmarca a un objetivo.
///			Se dibuja a partir de 8 imágenes y se adapta
///			a la posición y al tamaño del objetivo cuando cambia.
/// 		Uso: recibe un FlxObject y un directorio donde buscar
///			las imagenes del cuadro. Se adapta a la posición y el
///			tamaño del objeto en cada llamada a update().
//////////////////////////////////////////////////////////////////
class Frame extends FlxObject 
{
	///////////////////////////////////////////////
	/// \brief: Constructor
	/// \param: Objetivo, objeto cuya posición y tamaño se rastreará
	/// \param: Directorio donde están las imágenes del cuadro (topleft.png, etc...)
	///////////////////////////////////////////////
	public function new(Target: FlxObject, imgFolder: String = "assets/img/frame")
	{
		super();
		_target = Target;
		topleft = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"topleft.png");
		topright = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"topright.png");
		top = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"top.png");
		left = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"left.png");
		right = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"right.png");
		bottomleft = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"bottomleft.png");
		bottomright = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"bottomright.png");
		bottom = new FlxSprite(_target.x, _target.y, imgFolder+"/"+"bottom.png");
		canvas = new FlxSprite(_target.x, _target.y);
		// Ojo! El canvas tiene que tener suficiente tamaño, no será redimensionado
		canvas.makeGraphic(600, 500, 0xffffffff, true);

		_targetLastSize = new FlxPoint();
		_targetLastSize.x = _target.width;
		_targetLastSize.y = _target.height;
		repaint_canvas();
	}


	///////////////////////////////////////////////
	/// \brief: Actualiza el cuadro, rastreando la posición y tamaño del target
	///////////////////////////////////////////////
	public override function update()
	{
		// ajusta la posición del frame al target
		canvas.x = _target.x -  left.width;
		canvas.y = _target.y -  top.height;
		
		if (_targetLastSize.x != _target.width || _targetLastSize.y != _target.height)
		{
			_targetLastSize.x = _target.width;
			_targetLastSize.y = _target.height;
			repaint_canvas();
		}
	}
	

	///////////////////////////////////////////////
	/// \brief: Dibuja el frame en la posición del target
	///////////////////////////////////////////////
	public override function draw(){
		canvas.draw();
	}
	

	///////////////////////////////////////////////
	/// \brief: Actualiza el tamaño del frame
	///////////////////////////////////////////////
	private function repaint_canvas(){
		var _neededWidth = Std.int(left.width + _target.width + right.width);
		var _neededHeight = Std.int(top.height + _target.height + bottom.height);
		// limpia el canvas
		canvas.pixels.fillRect(new flash.geom.Rectangle(0, 0, _neededWidth, _neededHeight), 0x00000000 );
		
		
		// ajustamos la escala y el origen de los sprites de tamaño ajustable
		top.setGraphicSize(Std.int(_neededWidth-right.width-left.width), Std.int(top.height));
		top.origin.set(0, 0);
		left.setGraphicSize(Std.int(left.width), Std.int(_neededHeight-bottom.height-top.height));
		left.origin.set(0, 0);
		right.setGraphicSize(Std.int(topright.width), Std.int(_neededHeight-topright.height-bottomright.height));
		right.origin.set(0, 0);
		bottom.setGraphicSize(Std.int(_neededWidth-bottomleft.width-right.width), Std.int(bottom.height));
		bottom.origin.set(0, 0);
		
		//// pinta el frame sobre el canvas
		canvas.stamp(left, 0, Std.int(top.height));
		canvas.stamp(top, Std.int(left.width), 0);
		canvas.stamp(right, Std.int(left.width + _target.width), Std.int(top.height));
		canvas.stamp(bottom, Std.int(bottomleft.width), Std.int(top.height + _target.height));
		canvas.stamp(topleft, 0, 0);
		canvas.stamp(topright, Std.int(left.width + _target.width + right.width - topright.width), 0);
		canvas.stamp(bottomleft, 0, Std.int(top.height + _target.height));
		canvas.stamp(bottomright, Std.int(left.width + _target.width), Std.int(top.height + _target.height));
		
		// actualiza el rectangulo de textura que se dibuja
		canvas.frame.frame.left = canvas.frame.frame.top = 0;
		canvas.frame.frame.right = _neededWidth;
		canvas.frame.frame.bottom = _neededHeight;
		canvas.updateFrameData();
		canvas.origin.set(0, 0);
	}

	public function set_alpha(Alpha: Float): Float
	{
		canvas.alpha = Alpha;
		return canvas.alpha;
	}

	public function get_alpha(): Float
	{
		return canvas.alpha;
	}

	private var _target: FlxObject;		// el objeto que queremos enmarcar
	private var topleft: FlxSprite;		// sprites que forman el cuadro
	private var topright: FlxSprite;
	private var top: FlxSprite;
	private var left: FlxSprite;
	private var right: FlxSprite;
	private var bottomleft: FlxSprite;
	private var bottomright: FlxSprite;
	private var bottom: FlxSprite;
	private var canvas: FlxSprite;			/// sprite que contiene la representación grafica del cuadro
	private var _targetLastSize: FlxPoint;	/// helper variable para llevar rastro del ultimo tamaño del target y saber cuando cambia
	public var alpha(get, set): Float;
}